"""
python 3.x 里所有的类都有一个共同的父类 —— object()
object 的实例是不可变的，不能像该对象添加属性

object 提供了一些基础方法:
str()：返回对象的字符串表示（默认为对象的内存地址）。
repr()：返回对象的正式字符串表示。
eq(other)：判断两个对象是否相等。
ne(other)：判断两个对象是否不相等。
hash()：返回对象的哈希值，使对象可以用作字典的键。

object() 可以作为占位符使用

# NOT_SET = object()
#
# def my_func(value=NOT_SET):
#     if value is NOT_SET:
#         print("Value is not set.")
#     else:
#         print(f"Value is {value}")
#
# my_func()  # 输出：Value is not set.
# my_func(10)  # 输出：Value is 10

"""



class Dog:
    """ once simple try to simulate little dog"""

    def __init__(self, name, age, color):
        """ initialize name & age """
        self.name = name
        self.age = age
        self.color = color
        self.mile = 0  # default val
        self.__count = 0  # private val

    def sit(self):
        print(f"{self.name} is now sitting.")

    def roll_over(self):
        print(f"{self.name} rolled over!")

    def run(self, mile):
        self.update_mile(mile)

    def update_mile(self, mile):
        self.mile += mile

    def do(self):
        self.__count += 1
        print(f"this is do:{self.__count}")

    def __sdo(self):
        self.__count += 1
        print(f"this is sdo:{self.__count}")


# -----------------------------------

class Teddy(Dog):   # Dog的子类
    """ 子类 """
    # 使用赋值语句定义类属性，记录所有工具对象的数量
    count = 0

    def __init__(self, name, age, color):
        super().__init__(name, age, color)  # 继承父类的初始化属性
        self.height = 30    # 子类自己的属性
        Teddy.count += 1

    # 定义子类自己的方法
    def outputHeight(self):
        print(f"Teddy's height is {self.height} cm.")

    # 重载，覆盖父类的方法
    def run(self, mile):
        self.mile += mile
        super().run(mile)   # 调用父类中封装的方法

    # def zdo(self):    # 子类无法直接调用父类的私有属性和私有方法
    #     print(self.__count)


# -----------------------------------

if __name__ == '__main__':
    my_dog = Dog("Willie", 6, "yellow")

    print(f"My dog's name is {my_dog.name}.")
    print(f"Mydog is {my_dog.age} years old.")

    my_dog.run(10)
    print(f"dog had run {my_dog.mile} km")
    my_dog.run(5)
    print(f"dog had run {my_dog.mile} km")

    my_teddy = Teddy("Tony", 2, "brown")
    my_teddy.outputHeight()

    my_teddy.do()   # 通过父类的公有方法简介访问到私有属性或私有方法
    # my_teddy.__sdo()  # 错误
    # my_teddy.zdo()

    you_teddy = Teddy("Sam", 5, "green")
    he_teddy = Teddy("Tom", 4, "green")
    print(Teddy.count)
    # print(he_teddy.count)     # 不推荐使用这种方法
